﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using MonkeyShop.Admin.Biz.Data;

namespace MonkeyShop.Admin.Biz
{
    public class AdminUserBiz
    {
        #region Select methods

        /// <summary>
        /// Gets the by identifier.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns></returns>
        public Employee GetById(int id)
        {
            if (id <= 0) return null;
            using (var db = new MonkeyShopAdminEntities())
            {
                return db.Employees.FirstOrDefault(x => x.Id == id);
            }
        }

        /// <summary>
        /// Logons the specified user name.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <param name="password">The password.</param>
        /// <returns></returns>
        public Employee Logon(string userName, string password)
        {
            using (var db = new MonkeyShopAdminEntities())
            {
                return db.Employees.FirstOrDefault(e => e.UserName == userName && e.Password == password);
            }
        }

        /// <summary>
        /// Gets the name of the by.
        /// </summary>
        /// <param name="userName">Name of the user.</param>
        /// <returns></returns>
        public Employee GetByName(string userName)
        {
            using (var db = new MonkeyShopAdminEntities())
            {
                return db.Employees.FirstOrDefault(e => e.UserName == userName);
            }
        }

        /// <summary>
        /// Gets the employees.
        /// </summary>
        /// <param name="startIndex">The start index.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="sorting">The sorting.</param>
        /// <param name="name">The name.</param>
        /// <param name="totalRecords">The total records.</param>
        /// <returns></returns>
        public IList<Employee> GetEmployees(int startIndex, int pageSize, string sorting, string name, out int totalRecords)
        {
            using (var db = new MonkeyShopAdminEntities())
            {
                var query = db.Employees.Where(x => x.UserName != "admin");

                // filter
                if (!string.IsNullOrEmpty(name))
                {
                    query = query.Where(x => x.Name.Contains(name));
                }

                totalRecords = query.Count();

                return pageSize > 0
                           ? query.OrderBy(sorting).Skip(startIndex).Take(pageSize).ToList() //Paging
                           : query.ToList(); //No paging
            }
        }

        /// <summary>
        /// Gets the next code.
        /// </summary>
        /// <returns></returns>
        public int GetNextCode()
        {
            long? identity;
            using (var db = new MonkeyShopAdminEntities())
            {
                identity = db.GetIdentity("Employees").SingleOrDefault();
            }

            return identity.HasValue ? (int)identity.Value + 1 : 0;
        }
        
        #endregion
        
        #region CRUD methods

        /// <summary>
        /// Creates the employee.
        /// </summary>
        /// <param name="employee">The employee.</param>
        /// <returns></returns>
        /// <exception cref="System.ApplicationException">UserNameIsExisted</exception>
        public Employee CreateEmployee(Employee employee)
        {
            // validate inputs
            if (employee == null) return null;
            if (string.IsNullOrEmpty(employee.Code) || string.IsNullOrEmpty(employee.Name)) return null;

            // is existed username
            using (var db = new MonkeyShopAdminEntities())
            {
                var existedEmp = db.Employees.FirstOrDefault(x => x.UserName == employee.UserName);
                if (existedEmp != null)
                    throw new ApplicationException("UserNameIsExisted");

                db.Employees.Add(employee);
                db.SaveChanges();
            }

            return employee;
        }

        /// <summary>
        /// Deletes the employee.
        /// </summary>
        /// <param name="employeeId">The employee identifier.</param>
        /// <exception cref="System.ApplicationException">DeleteFailed</exception>
        public void DeleteEmployee(int employeeId)
        {
            if (employeeId <= 0) return;

            using (var db = new MonkeyShopAdminEntities())
            {
                var employee = db.Employees.FirstOrDefault(x => x.Id == employeeId);
                if (employee == null || employee.Id == 1 || employee.UserName == "admin")
                    throw new ApplicationException("DeleteFailed");

                db.Entry(employee).State = EntityState.Deleted;
                db.SaveChanges();
            }
        }

        /// <summary>
        /// Updates the employee.
        /// </summary>
        /// <param name="employee">The employee.</param>
        /// <exception cref="System.ApplicationException">
        /// UserNamePasswordRequired
        /// or
        /// UserNameIsExisted
        /// </exception>
        public void UpdateEmployee(Employee employee)
        {
            if (employee == null || employee.Id <= 0) return;
            if (string.IsNullOrEmpty(employee.UserName) || string.IsNullOrEmpty(employee.Password))
            {
                throw new ApplicationException("UserNamePasswordRequired");
            }
            using (var db = new MonkeyShopAdminEntities())
            {
                var countExisted = db.Employees.Count(x => x.Id != employee.Id && x.UserName == employee.UserName);
                if (countExisted > 0)
                    throw new ApplicationException("UserNameIsExisted");

                db.Employees.Attach(employee);
                db.Entry(employee).State = EntityState.Modified;
                db.SaveChanges();
            }
        }

        #endregion
    }
}
